#include "StdAfx.h"
#include "FrameBuffer.h"

CFrameBuffer::CFrameBuffer(void)
	: buffer(NULL), rows(0), columns(0)
{
}

CFrameBuffer::~CFrameBuffer(void)
{
	FreeBuffer();
}

CharAttribute CFrameBuffer::Blank(L' ', White, Black, 0);

const CharAttribute& CFrameBuffer::operator () (int row, int column) const
{
	ASSERT(row >= 0 && row <= rows-1 && column >=0 && column <= columns-1);
	return this->buffer[row][column];
}

void CFrameBuffer::CreateBuffer (int rows, int columns)
{
	FreeBuffer();

	ASSERT(rows > 0 && columns > 0);
	this->rows = rows;
	this->columns = columns;

	this->buffer = new CharAttribute*[rows];
	VERIFY(this->buffer != NULL);
	for (int i = 0; i < rows; i ++)
	{
		this->buffer[i] = new CharAttribute[columns];
		VERIFY(this->buffer[i] != NULL);
	}
}

void CFrameBuffer::SetCharAttributeAt (int row, int column, CharAttribute c)
{
	ASSERT(row >= 0 && row <= this->rows-1 && column >=0 && column <= this->columns-1);
	ASSERT(c.Foreground >= Black && c.Foreground <= White);
	ASSERT(c.Background >= Black && c.Background <= White);
	ASSERT((c.Attributes & ~(Blink|Bold|Inverse|Underline)) == 0);

	this->buffer[row][column] = c;
}

void CFrameBuffer::ScrollUp ()
{
	CharAttribute* temp = this->buffer[0];

	for (int r = 0; r < rows-1; r ++)
		this->buffer[r] = this->buffer[r+1];

	for (int c = 0; c < columns; c ++)
		temp[c] = Blank;

	this->buffer[rows-1] = temp;
}

void CFrameBuffer::InsertLine (int row)
{
	ASSERT(row >= 0 && row <= this->rows-1);

	CharAttribute* temp = this->buffer[this->rows-1];

	for (int r = this->rows-1; r > row; r --)
		this->buffer[r] = this->buffer[r-1];

	for (int c = 0; c < this->columns; c ++)
		temp[c] = Blank;

	this->buffer[row] = temp;
}

void CFrameBuffer::FreeBuffer(void)
{
	if (this->buffer != NULL)
	{
		for (int i = 0; i < this->rows; i ++)
			delete[] this->buffer[i];

		delete this->buffer;
	}
}

bool CFrameBuffer::HasBold(unsigned char attributes)
{
    return (attributes & (unsigned char)Bold) != 0;
}

bool CFrameBuffer::HasBlink(unsigned char attributes)
{
    return (attributes & (unsigned char)Blink) != 0;
}

bool CFrameBuffer::HasInverse(unsigned char attributes)
{
    return (attributes & (unsigned char)Inverse) != 0;
}

bool CFrameBuffer::HasUnderline(unsigned char attributes)
{
    return (attributes & (unsigned char)Underline) != 0;
}
